home *** CD-ROM | disk | FTP | other *** search
- (******************************************************************************
-
- UNIT KBDEDIT
-
-
- -------------------------------------------------------------------------------
- Philippe Ranger (514) 274 4653
- First version 26-6-90 Present version 13-7-90
- -------------------------------------------------------------------------------
- SPECIFICATION
- Defines a lite-line-editor TFDD class, kbdEditC, and installs and opens
- one instance, ke. The text file is ke.t.
- Starting value of string self.s is treated as editable starting input. Reset
- to null on each read.
- One option is to allow user to use Esc key. This will return an empty string
- and set boolean Self.escUsed to true. Otherwise escUsed is false -- it
- will become false again on next read unless Esc is used again.
- Value of boolean echoCR sets whether the Enter that ends any keyboard read
- will be echoed to screen.
- As defined in TP, the CR itself is always recorded (but as ^M^J, as for an
- ordinary text). It remains in buffer until a readln is commanded.
- Convenience method StuffReadln (var srs) simply stuffs the present value
- of string srs (into self.s) before doing an edited readln on it.
- Editor input cannot be redirected.
-
- EDITOR SPEC
- Input from s, then kbd, read and echoed from present cursor position, to
- the last column but one in the current window. If window width > 127
- (??), will raise IO error 255.
- User allowed to edit input using ^S, ^D, ^H, ^G and equivalent left arrow,
- right arrow, backspace and Del, plus Home and End.
- Input normally ended with Enter or ^M. S is nulled.
- Self holds boolean toggle fields that can only be changed by clients:
- If echoCR, CR written to screen; else cursor brought to end of input.
- Iff doEsc, user allowed use of Esc, as specified above.
- Iff sdel, default starting input is deleted if first char from user is
- above #31.
- EchoCR is true by default, other toggles false.
-
- NOTE
- Underline before a class element name indicates that it is private.
- S and EchoCR are not private. They may be manipulated directly by class
- clients. If this is found embarrassing, field-manipulation methods may
- be added.
- ******************************************************************************)
-
- UNIT kbdEdit;
-
- INTERFACE
-
- USES tfdd;
-
- CONST
- Mx = 127; (*1 less than buffer size*)
- errorValue = 255;
-
- TYPE
- lineS = string[Mx];
-
- kbdEditC = object (tfddC)
- s: lineS;
- escUsed: boolean;
- echoCR, doEsc, sdel: boolean;
- procedure stuffReadln (var srs: lineS);
- function _readLine: integer;
- constructor init
- end;
-
- VAR ke: kbdEditC;
-
- IMPLEMENTATION
- (******************************************************************************
- METHODS
-
- ******************************************************************************)
-
- USES crt, dos;
-
- {$F+}
-
- PROCEDURE initialize; BEGIN ke.init; END;
-
-
- PROCEDURE kbdEditC.stuffReadln (var srs: lineS);
- BEGIN
- s := srs;
- readln (t, srs)
- END;
-
- FUNCTION kbdEditC._readLine: integer;
- (*=============================================================================
- PRE
- self.echoCR true iff user CR not to be echoed.
- self.s holds starting feed for read.
- -------------------------------------------------------------------------------
- POST
- See unit specification.
- Self.s is edited input, without CR.
- Returns error value.
- -------------------------------------------------------------------------------
- METHOD
- All commands, including none, listed in cmdT. Char test starts with normal
- chars, then sets cmd for any command char. Default cmd is none. Last,
- cmd is executed.
- =============================================================================*)
-
- TYPE cmdT = (none, left, right, del, bs, home, endc, exitc);
-
- VAR
- s0: byte absolute s; (*length(s))*)
- i: byte; (*cursor position in s*)
- c: char;
- cmd: cmdT;
- Nx: byte; (*present window width*)
- x, y: byte; (*whereX, whereY*)
- firstTap: boolean;
-
- procedure delAll; begin
- dec (x, i-1); gotoXY (x, y);
- fillchar (s[1], s0, ' ');
- write (s); gotoXY (x, y);
- s0 := 0; i := 1
- end;
-
- BEGIN
- _readLine := 0;
- escUsed := false;
- firstTap := true;
- Nx := lo(windMax) - lo(windMin) + 1;
- if Nx > Mx then begin _readLine := errorValue; EXIT end;
- x := whereX; y := whereY;
- if x + s0 >= Nx then s0 := Nx - x;
- write (s); i := s0+1; x := x + s0;
- while true do begin
- c := readkey;
- if firstTap and sdel and (c >= #32) then begin
- firstTap := false;
- delAll
- end;
- cmd := none;
- case c of
- #32..#255: if x < Nx then begin
- inc (s0);
- move (s[i], s[i+1], s0 - i);
- s[i] := c;
- write (copy (s, i, s0+1 - i));
- inc (i);
- inc (x); gotoXY (x, y)
- end;
- #0: case readkey of
- #75: cmd := left;
- #77: cmd := right;
- #83: cmd := del;
- #71: cmd := home;
- #79: cmd := endc
- end;
- ^M: cmd := exitc;
- ^[: if doEsc then begin delAll; escUsed := true; cmd := exitc end;
- ^H: cmd := bs;
- ^G: cmd := del;
- ^S: cmd := left;
- ^D: cmd := right
- end;
- case cmd of
- none: ;
- exitc: begin
- if echoCR then writeln
- else begin inc (x, s0-i); gotoXY (x, y) end;
- EXIT
- end;
- bs: if i > 1 then begin
- delete (s, i-1, 1); dec (i);
- dec (x); gotoXY (x, y);
- write (copy (s, i, s0+1 - i) + ' ');
- gotoXY (x, y)
- end;
- del: if i <= s0 then begin
- delete (s, i, 1);
- gotoXY (x, y);
- write (copy (s, i, s0+1 - i) + ' ');
- gotoXY (x, y)
- end;
- left: if i > 1 then begin dec(i); dec(x); gotoXY(x, y) end;
- right: if i <= s0 then begin inc(i); inc(x); gotoXY(x, y) end;
- home: begin dec (x, i-1); i := 1; gotoXY (x, y) end;
- endc: begin inc (x, s0-i); i := s0; gotoXY (x, y) end
- end
- end
- END; (*kbdEditC._readLine*)
-
-
- FUNCTION readEdit (var t: textRec): integer;
- (*=============================================================================
- PRE
- t open for input only;
- t.userData[1..4] holds a pointer to a kbdEditC instance.
- see kbdEditC._readLine.
- -------------------------------------------------------------------------------
- POST
- User allowed to input with kbdEditO._readLine's editing facilities.
- Result plus ^M^J read to t.
- -------------------------------------------------------------------------------
- NOTES
- Under TP's read convention, no kbd input is read until Enter (^M) is hit,
- and this is always read also as an eoln, ^M^J. This convention is fol-
- lowed here.
- It is not part of normal text file services that input should be echoed on
- screen. Echoing is the device driver's responsibility. Here it is handled
- within _readLine (which indeed could not work if it could not echo).
- =============================================================================*)
-
- VAR selfp: ^kbdEditC;
-
- BEGIN
- with t do begin
- bufEnd := 0;
- bufPos := 0;
- move (userData, selfp, sizeof(selfp));
- with selfp^ do begin
- readEdit := _readLine;
- move (s[1], bufPtr^, length(s));
- bufEnd := length(s);
- s := ''
- end;
- bufPtr^[bufEnd] := ^M; inc (bufEnd);
- bufPtr^[bufEnd] := ^J; inc (bufEnd)
- end
- END; (*readEdit*)
-
-
- CONSTRUCTOR kbdEditC.init;
- BEGIN
- tfddC.init;
- s := '';
- echoCR := true;
- doEsc := false;
- sdel := false;
- textRec(t).inoutFunc := @readEdit;
- reset (t)
- END;
-
-
- BEGIN INITIALIZE END.